package org.yunai.swjg.server.module.item.container;

import org.yunai.swjg.server.module.item.vo.Item;
import org.yunai.swjg.server.core.role.Role;
import org.yunai.yfserver.util.Assert;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 固定容量的道具容器
 * User: yunai
 * Date: 13-4-6
 * Time: 下午4:30
 */
public abstract class AbstractItemBag implements Bag<Item, Role> {

    /**
     * 同模版道具按照堆叠数升序
     */
    protected final Comparator<Item> overlapAscComp = new Comparator<Item>() {
        @Override
        public int compare(Item itemA, Item itemB) {
            if (itemA == null) {
                return itemB == null ? 0 : 1;
            }
            if (itemB == null) {
                return -1;
            }
            return itemA.getOverlap() - itemB.getOverlap();
        }
    };

    /**
     * 容器中的所有道具实例
     */
    protected Item[] items;
    /**
     * 容器的所有者
     */
    protected final Role owner;
    /**
     * 容器ID
     */
    private final BagType bagType;

    protected AbstractItemBag(Role owner, BagType bagType, int capacity) {
        Assert.notNull(owner);
        Assert.isTrue(capacity >= 0, "容量不能为负 :" + capacity);

        this.owner = owner;
        this.bagType = bagType;
        this.items = new Item[capacity];
    }

    /**
     * 添加道具<br />
     * 子类方法若要重写该方法，需要小心！
     *
     * @param item 道具
     */
    public void putItem(Item item) {
        Assert.notNull(item);

        if (checkIndex(item.getIndex())) {
            items[item.getIndex()] = item;
        }
    }

    /**
     * 移除指定位置移除道具<br />
     *
     * @param index 位置
     */
    public void removeItem(Integer index) {
        Assert.notNull(index);

        if (checkIndex(index)) {
            items[index] = null;
        }
    }

//  TODO  List<ItemEntity> toItemEntitys()

    @Override
    public Item getByIndex(int index) {
        return checkIndex(index) ? items[index] : null;
    }

    /**
     * 检查一个索引是否在本背包的索引允许范围内
     *
     * @param index 索引
     * @return 如果合法，返回true，否则返回false
     */
    public final boolean checkIndex(int index) {
        return index >= 0 && index < items.length;
    }

    @Override
    public int getCapacity() {
        return items.length;
    }

    // TODO public final List<Item> getAllIgnoreBind(String itemSN)

    // TODO public final List<Item> getAllConsiderBind(String itemSN, BindStatus bind)

//    public final void getAllByTemplateId(Integer templateId, Collection<Item> result) {
//        Assert.notNull(result);
//    }

    /**
     * 通过玩家道具编号获得玩家道具
     *
     * @param id 玩家道具编号
     * @return 玩家道具
     */
    // TODO 未测试
    public final Item getById(Integer id) {
        for (Item item : items) {
            if (item == null) {
                continue;
            }
            if (item.getId().equals(id)) {
                return item;
            }
        }
        return null;
    }

    /**
     * @param templateId 道具模版编号
     * @return 指定道具模版编号的所有道具列表
     */
    public final List<Item> getByTemplateId(Integer templateId) {
        List<Item> list = new ArrayList<>();
        for (Item item : items) {
            if (item == null) {
                continue;
            }
            if (item.getTemplate().getId() == templateId) {
                list.add(item);
            }
        }
        return list;
    }

    @Override
    public Role getOwner() {
        return owner;
    }

    @Override
    public BagType getBagType() {
        return bagType;
    }

    /**
     * @return 返回所有非空道具的列表
     */
    public final List<Item> getAll() {
        List<Item> itemList = new ArrayList<Item>(getCapacity());
        for (Item item : items) {
            if (!Item.isEmpty(item)) {
                itemList.add(item);
            }
        }
        return itemList;
    }

    // TODO public final int getCountIgnoreBind(String itemSN) {

//    public final int getCountConsiderBind(String itemSN,
// Bindable.BindStatus bindStatus) {

    /**
     * 获得指定道具模版在背包中的数量
     *
     * @param templateId 道具模版编号
     * @return 道具模版数量
     */
    public final int getCountByTemplateId(Integer templateId) {
        int count = 0;
        for (Item item : items) {
            if (item != null && item.getTemplate().getId() == templateId) {
                count++;
            }
        }
        return count;
    }

//  TODO  public static boolean isPrimBag(BagType bag) {

//   TODO 	public static boolean isNullBag(BagType bag) {

//   TODO  	public Item getEmptySlot() { 被getFirstEmptyIndex取代

    /**
     * 获得第一个空格位置
     *
     * @return 第一个空格位置
     */
    public Integer getFirstEmptyIndex() {
        int index = 0;
        for (Item item : items) {
            if (item == null) {
                return index;
            }
            index++;
        }
        return null;
    }

    /**
     * 获得剩余空间大小
     *
     * @return 剩余空间大小
     */
    public Integer remain() {
        int count = 0;
        for (Item item : items) {
            count++;
        }
        return count;
    }
}
